#include "StdAfx.h"
#include "xfRefEdge.h"

xfRefEdge::xfRefEdge(void)
{
	memset(m_szEdgeFile,0,sizeof(m_szEdgeFile));
	ClearEdge();
}

xfRefEdge::~xfRefEdge(void)
{
}



int xfRefEdge::ClearEdge()
{
    memset(&m_xEdgeHead,0,sizeof(m_xEdgeHead));
	m_xBuffer.MemSet();
	m_fEdgeThreshold = 0.0f;

	return 0;
}


int xfRefEdge::AddAdjEdge(zkImgBitInfo *pImgInfo,DWORD dwImgBinary)
{
	if( NULL == pImgInfo )
	{
		return DD_ERR_PARAMETER;
	}

	DWORD dwWidth  = (DWORD)pImgInfo->nWidth;
	DWORD dwHeight = (DWORD)pImgInfo->nHeight;
	DWORD dwSize   = dwWidth * dwHeight;

	zkAnalyEdgeHead *pHead = &m_xEdgeHead;

	if( 0 == pHead->dwRecCount )
	{
		DWORD lBufSize = dwSize * sizeof(WORD)*2;

		if( !m_xBuffer.Allocate(lBufSize) )
		{
			return DD_ERR_NEWBUFFER;
		}

		BYTE *pBuffer     = m_xBuffer.pBuffer;

		pHead->dwHeight   = dwHeight;
		pHead->dwWidth    = dwWidth;
		pHead->dwImgBinary = dwImgBinary;
		pHead->dwMaxRed   = 0;
		pHead->dwMinBlue  = 0;
		pHead->dwRecCount = 0;
		pHead->fEdgeThreshold = m_fEdgeThreshold;
		pHead->pwEdges1   = (WORD*)( pBuffer );
		pHead->pwEdges2   = (WORD*)( pBuffer + dwSize * sizeof(WORD) );
	}
	else
	{
		if( pHead->dwHeight != dwHeight || pHead->dwWidth != dwWidth )
		{
			return DD_ERR_IMG_SIZENOTMATCH;
		}
	}
	if( 0 == pHead->dwImgBinary )
	{
		pHead->dwImgBinary = dwImgBinary;
	}

	DWORD i=0;

	if( pHead->dwRecCount == 60000 )
	{
		pHead->dwRecCount = 30000; 

		for(i=0;i<dwSize;i++)
		{
			pHead->pwEdges1[i] = (pHead->pwEdges1[i]+1)>>1;
			pHead->pwEdges2[i] = (pHead->pwEdges2[i]+1)>>1;
		}
	}

	switch( pImgInfo->nImgDefine )
	{
	case eImage_Define_Img8:
		{

		}
		break;
	case eImage_Define_Img16:
		{
			WORD *pData = (WORD*)pImgInfo->pImageData;
			for(i=0;i<dwSize;i++)
			{
				if( pData[i] > dwImgBinary   )
				{
					pHead->pwEdges1[i] += 1;
				}
			}
		}
		break;
	default:
		break;
	}

	pHead->dwRecCount++;

	SaveEdge();

	return 0;
}

int xfRefEdge::AddSubEdge(zkImgBitInfo *pImgInfo,DWORD dwMaxRed,DWORD dwMinBlue)
{
	if( NULL == pImgInfo || dwMinBlue <= dwMaxRed )
	{
		return DD_ERR_PARAMETER;
	}

	DWORD dwWidth  = (DWORD)pImgInfo->nWidth;
	DWORD dwHeight = (DWORD)pImgInfo->nHeight;
	DWORD dwSize   = dwWidth * dwHeight;

	zkAnalyEdgeHead *pHead = &m_xEdgeHead;

	if( 0 == pHead->dwRecCount )
	{
		DWORD lBufSize = dwSize * sizeof(WORD)*2;

		if( !m_xBuffer.Allocate(lBufSize) )
		{
			return DD_ERR_NEWBUFFER;
		}

		BYTE *pBuffer     = m_xBuffer.pBuffer;

		pHead->dwHeight   = dwHeight;
		pHead->dwWidth    = dwWidth;
		pHead->dwImgBinary = 0;
		pHead->dwMaxRed   = dwMaxRed;
		pHead->dwMinBlue  = dwMinBlue;
		pHead->dwRecCount = 0;
		pHead->fEdgeThreshold = m_fEdgeThreshold;
		pHead->pwEdges1   = (WORD*)( pBuffer );
		pHead->pwEdges2   = (WORD*)( pBuffer + dwSize * sizeof(WORD) );
	}
	else
	{
        if( pHead->dwHeight != dwHeight || pHead->dwWidth != dwWidth )
		{
			return DD_ERR_IMG_SIZENOTMATCH;
		}
	}
	if( 0 == pHead->dwMaxRed && 0 == pHead->dwMinBlue )
	{
		pHead->dwMaxRed   = dwMaxRed;
		pHead->dwMinBlue  = dwMinBlue;
	}
	
	DWORD i=0;

	if( pHead->dwRecCount == 60000 )
	{
        pHead->dwRecCount = 30000; 

		for(i=0;i<dwSize;i++)
		{
			pHead->pwEdges1[i] = (pHead->pwEdges1[i]+1)>>1;
			pHead->pwEdges2[i] = (pHead->pwEdges2[i]+1)>>1;
		}
	}

	switch( pImgInfo->nImgDefine )
	{
	case eImage_Define_Img8:
		{

		}
		break;
	case eImage_Define_Img16:
		{
			WORD *pData = (WORD*)pImgInfo->pImageData;
            for(i=0;i<dwSize;i++)
			{
				if( pData[i] < dwMaxRed ||
					pData[i] > dwMinBlue   )
				{
					pHead->pwEdges1[i] += 1;
				}
// 				else if( pData[i] > dwMinBlue )
// 				{
//                     pHead->pwEdges2[i] += 1;
// 				}
			}
		}
		break;
	default:
		break;
	}

	pHead->dwRecCount++;

	SaveEdge();

	return 0;
}


int xfRefEdge::SetEdgeConditionThreshold(float fThreshold)
{
	if( fThreshold<0 || fThreshold > 100 )
	{
		fThreshold = 10;
	}

	m_fEdgeThreshold           = fThreshold;
	m_xEdgeHead.fEdgeThreshold = fThreshold;

	SaveEdge();

	return 0;
}


#include "DDReadWriteFile.h"

int xfRefEdge::SetEdgeFile(char *pFileName)
{
	strcpy(m_szEdgeFile,pFileName);

	return 0;
}

int xfRefEdge::LoadEdge()
{
	int nRet = -1;

	DDReadWriteFile xFile;
    zkAnalyEdgeHead *pHead = &m_xEdgeHead;

	do 
	{
		char *pFileName = m_szEdgeFile;

#ifdef DD_NEW_EDGE
		char xBuffer[1024]={0};

		BITMAPFILEHEADER *pBitFileHead = (BITMAPFILEHEADER*)xBuffer;
		BITMAPINFOHEADER *pBitInfoHead = (BITMAPINFOHEADER*)( xBuffer + sizeof(BITMAPFILEHEADER) );

		LONGLONG llFileSize = 0;
		if( 0 != xFile.DDCreateFile(pFileName,TRUE,&llFileSize) )
		{
			nRet = -1;
			break;
		}
		LONGLONG llFileOffset = 0;
		nRet = xFile.DDOperatorFile( (BYTE*)xBuffer,sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER),&llFileOffset);
		if( nRet != 0)
		{
			break;
		}

		DWORD dwWidth  = pBitInfoHead->biWidth;
		DWORD dwHeight = pBitInfoHead->biHeight;
		DWORD dwSize   = dwWidth * dwHeight;
		DWORD lBufSize = dwSize * sizeof(WORD)*2;
		if( !m_xBuffer.Allocate(lBufSize) )
		{
			nRet = DD_ERR_NEWBUFFER;
			break;
		}
        m_xBuffer.MemSet();
		WORD *pwEdges = (WORD*)m_xBuffer.pBuffer;

		llFileOffset = pBitFileHead->bfOffBits;

		BYTE *pBmpBuffer = new BYTE[ dwSize+4];
		if( NULL == pBmpBuffer )	
		{
			break;
		}
		memset(pBmpBuffer,0,dwSize);
		nRet = xFile.DDOperatorFile( pBmpBuffer,dwSize,&llFileOffset);
		if( nRet != 0)
		{
			delete []pBmpBuffer;
			break;
		}

		llFileOffset = llFileSize - 4*sizeof(DWORD);
		nRet = xFile.DDOperatorFile( (BYTE*)&(pHead->dwRed),sizeof(DWORD),&llFileOffset);
		if( nRet != 0)
		{
			delete []pBmpBuffer;
			break;
		}
		nRet = xFile.DDOperatorFile( (BYTE*)&(pHead->dwGreen),sizeof(DWORD),&llFileOffset);
		if( nRet != 0)
		{
			delete []pBmpBuffer;
			break;
		}
		nRet = xFile.DDOperatorFile( (BYTE*)&(pHead->dwRedAdjust),sizeof(DWORD),&llFileOffset);
		if( nRet != 0)
		{
			delete []pBmpBuffer;
			break;
		}
		nRet = xFile.DDOperatorFile( (BYTE*)&(pHead->dwGreenAdjust),sizeof(DWORD),&llFileOffset);
		if( nRet != 0)
		{
			delete []pBmpBuffer;
			break;
		}

		for(DWORD i=0;i<dwSize;i++)
		{
           pwEdges[i] = pBmpBuffer[i];
		}

		delete []pBmpBuffer;

		m_fEdgeThreshold = 1.0f;

		pHead->dwWidth  = dwWidth;
		pHead->dwHeight = dwHeight;
#else
		LONGLONG llFileSize = 0;
		if( 0 != xFile.DDCreateFile(pFileName,TRUE,&llFileSize) )
		{
			nRet = -1;
			break;
		}
		LONGLONG llFileOffset = 0;
		nRet = xFile.DDOperatorFile( (BYTE*)pHead,sizeof(zkAnalyEdgeHead),&llFileOffset);
		if( nRet != 0)
		{
			break;
		}
		// 		if( !pHead->CheckVersion() )
		// 		{
		// 			nRet = -1;
		// 			break;
		// 		}
		m_fEdgeThreshold = pHead->fEdgeThreshold;
		DWORD dwWidth  = pHead->dwWidth;
		DWORD dwHeight = pHead->dwHeight;
		DWORD dwSize   = dwWidth * dwHeight;
		DWORD lBufSize = dwSize * sizeof(WORD)*2;
		if( !m_xBuffer.Allocate(lBufSize) )
		{
			nRet = DD_ERR_NEWBUFFER;
			break;
		}
		BYTE *pBuffer = m_xBuffer.pBuffer;
		nRet = xFile.DDOperatorFile( pBuffer,lBufSize,&llFileOffset);
		if( nRet != 0)
		{
			break;
		}
		pHead->pwEdges1   = (WORD*)( pBuffer );
		pHead->pwEdges2   = (WORD*)( pBuffer + dwSize * sizeof(WORD) );
#endif

		return nRet;

	} while (FALSE);

	pHead->pwEdges1   = NULL;
	pHead->pwEdges2   = NULL;

	memset(pHead,0,sizeof(zkAnalyEdgeHead));

	return nRet;
}

int xfRefEdge::SaveEdge()
{
	return 0;

	int nRet = -1;

	if( NULL == m_xBuffer.pBuffer || 0 == m_xEdgeHead.dwRecCount )
	{
		return DD_ERR_PARAMETER;
	}

	DDReadWriteFile xFile;

	do 
	{
		char *pFileName = m_szEdgeFile;

		LONGLONG llFileSize = 0;

		if( 0 != xFile.DDCreateFile(pFileName,FALSE,&llFileSize) )
		{
			nRet = -1;
			break;
		}	

		LONGLONG llFileOffset = 0;

		zkAnalyEdgeHead *pHead = &m_xEdgeHead;
		pHead->dwFileVersion = DD_ANALY_VERSION_2012;
		nRet = xFile.DDOperatorFile( (BYTE*)pHead,sizeof(zkAnalyEdgeHead),&llFileOffset,FALSE);
		if( nRet != 0)
		{
			break;
		}

		DWORD dwWidth  = pHead->dwWidth;
		DWORD dwHeight = pHead->dwHeight;
		DWORD dwSize   = dwWidth * dwHeight;
		DWORD lBufSize = dwSize * sizeof(WORD)*2;
		BYTE *pBuffer  = m_xBuffer.pBuffer;

		nRet = xFile.DDOperatorFile( pBuffer,lBufSize,&llFileOffset,FALSE);
		if( nRet != 0)
		{
			break;
		}

	} while (FALSE);

	return nRet;
}